﻿#include "ssDBThread.h"
#include "log/ssLogThread.h"

namespace StarSeeker
{


ssDBThreadBase::ssDBThreadBase()
{
	m_queryLog = false;
}

ssDBThreadBase::~ssDBThreadBase()
{
}

bool ssDBThreadBase::Init(const char *pIP, u32 port, const char *pAccount, const char *pPW, const char *pDBName)
{
	return m_mysqlQuery.Init(pIP, port, pAccount, pPW, pDBName);
}

void ssDBThreadBase::HandleMessage(ssMsg_s &m)
{
	if (m.msgID == SS_MSG_RECRIVE)
	{
		//解析网络消息
		ssNetMsgHead* head = (ssNetMsgHead*)m.param[1];
		char* data = (char*)m.param[1];
        OnDBMsg(head, data + sizeof(ssNetMsgHead), head->m_dwLen - sizeof(ssNetMsgHead), (u32)m.param[0]);
		delete[] data;
	}
	else
	{
		OnOtherMsg(m);
	}

	//if (ret)
	//{
	//	//!!需要对象池
	//	delete[] data;
	//}
	//else
	//{
	//	PostMsg(m);
	//}
}

bool ssDBThreadBase::OnDBMsgNullRecord(u32 id, ssNetMsgHead* pHead, const char* pData, const u32 dataLen, u32 connectID)
{
	if (0 == m_mysqlQuery.QueryByIDStreaming(id, dataLen, pData))
	{
		if (m_mysqlQuery.GetResultFlag(id) & DB_RESULT_INSERT_ID)
		{
			u32 row = (u32)m_mysqlQuery.m_affectedRows;
			u32 inId = (u32)m_mysqlQuery.m_insertID;
			ssDBResParam rp = {};
			//!!需要对象池
			ulint* param = (ulint*)(pData + (dataLen - cg_ulint_size));
			rp.param = *param;
			rp.row = row;
			rp.insertId = inId;
			u32 sendLen = sizeof(ssNetMsgHead) + sizeof(ssDBResParam);
			pHead->m_dwLen = sendLen;
			char* sendBuf = new char[sendLen + 8];
			memcpy(sendBuf, pHead, sizeof(ssNetMsgHead));
			memcpy(sendBuf + sizeof(ssNetMsgHead), &rp, sizeof(ssDBResParam));
			SendResponse(connectID, (ssNetMsgHead*)sendBuf, sendBuf, sendLen);
		}
	}
	else
	{
		SS_LOG->Error(m_mysqlQuery.m_error.c_str());
	}
	return true;
}

bool ssDBThreadBase::OnDBMsgOneRecord(u32 id, ssNetMsgHead* pHead, const char* pData, const u32 dataLen, u32 connectID)
{
	i32 ret = m_mysqlQuery.QueryByIDStreaming(id, dataLen, pData);
	if (0 == ret)
	{
		ssReadBytes wb;
		ret = m_mysqlQuery.GetOneResult(id, wb);
		if (0 == ret)
		{
			u32 row = (u32)m_mysqlQuery.GetRows();
			ssDBResParam rp = {};

			ulint* param = (ulint*)(pData + (dataLen - cg_ulint_size));
			rp.param = *param;
			rp.row = row;
			u32 sendLen = sizeof(ssNetMsgHead) + sizeof(ssDBResParam) + (u32)wb.MaxSize();
			pHead->m_dwLen = sendLen;
			char* sendBuf = new char[sendLen + 8];
			if (m_queryLog)
			{
				SS_LOG->PrintEx("[%lld]OnDBMsgOneRecord id:%x td:%u", rp.param, id, m_ThreadId);
			}

			memcpy(sendBuf, pHead, sizeof(ssNetMsgHead));
			memcpy(sendBuf + sizeof(ssNetMsgHead), &rp, sizeof(ssDBResParam));
			if (row > 0 && !wb.IsEmpty())
			{
				memcpy(sendBuf + sizeof(ssNetMsgHead) + sizeof(ssDBResParam), wb.Buf(), wb.MaxSize());
			}
			SendResponse(connectID, (ssNetMsgHead*)sendBuf, sendBuf, sendLen);
		}
		else
		{
			SS_LOG->Error(m_mysqlQuery.m_error.c_str());
		}
	}
	else
	{
		SS_LOG->Error(m_mysqlQuery.m_error.c_str());
	}
	return true;
}

bool ssDBThreadBase::OnDBMsgMultiRecord(u32 id, ssNetMsgHead* pHead, const char* pData, const u32 dataLen, u32 connectID)
{
	if (0 == m_mysqlQuery.QueryByIDStreaming(id, dataLen, pData))
	{
		std::pair<int, ssLineBuffer&> ob = m_mysqlQuery.GetResultSet(id);
		if (0 == ob.first)
		{
			u32 row = (u32)m_mysqlQuery.GetRows();
			ssDBResParam rp = {};

			ulint* param = (ulint*)(pData + (dataLen - cg_ulint_size));
			rp.param = *param;
			rp.row = row;
			u32 sendLen = sizeof(ssNetMsgHead) + sizeof(ssDBResParam) + (u32)ob.second.Size();
			pHead->m_dwLen = sendLen;
			char* sendBuf = new char[sendLen + 8];
			char* sendFirst = sendBuf;
			if (m_queryLog)
			{
				SS_LOG->PrintEx("[%lld]OnDBMsgMultiRecord id:%x td:%u", rp.param, id, m_ThreadId);
			}

			memcpy(sendBuf, pHead, sizeof(ssNetMsgHead));
			sendBuf += sizeof(ssNetMsgHead);
			memcpy(sendBuf, &rp, sizeof(ssDBResParam));
			if (row > 0)
			{
				sendBuf += sizeof(ssDBResParam);
				memcpy(sendBuf, ob.second.Buf(), ob.second.Size());
			}
			SendResponse(connectID, (ssNetMsgHead*)sendFirst, sendFirst, sendLen);
		}
		else
		{
			SS_LOG->Error(m_mysqlQuery.m_error.c_str());
		}
	}
	else
	{
		SS_LOG->Error(m_mysqlQuery.m_error.c_str());
	}
	return true;
}

void ssDBThreadBase::OnDBMsgCleanBuffer()
{
	m_mysqlQuery.CleanBuffer();
}

bool ssDBThreadBase::OnOtherMsg(ssMsg_s &m)
{
	if (m.msgID == SS_MSG_THREAD)
	{
		if (m.subID == SS_DBEV_CLEAR_BUFFER)
		{
			OnDBMsgCleanBuffer();
		}
	}
	return true;
}

}
